<!--
 * @Author: 秦少卫
 * @Date: 2024-04-25 15:30:54
 * @LastEditors: 秦少卫
 * @LastEditTime: 2024-07-06 17:13:28
 * @Description: 我的素材
-->

<template>
  <div class="my-material">
    <Button icon="md-cloud-upload" @click="showUploadModal = true" long type="primary">
      {{ $t('myMaterial.uploadBtn') }}
    </Button>

    <!-- 上传素材弹窗 -->
    <Modal v-model="showUploadModal" title="上传素材" width="600" @on-ok="handleUpload">
      <Form ref="formRef" :model="formData" :rules="rules" label-position="top">
        <FormItem label="素材名称" prop="name">
          <Input v-model="formData.name" placeholder="请输入素材名称" />
        </FormItem>

        <FormItem label="素材类型" prop="type_id">
          <Select v-model="formData.type_id" placeholder="请选择素材类型">
            <Option v-for="item in typeList" :key="item.id" :value="item.id">
              {{ item.name }}
            </Option>
          </Select>
        </FormItem>

        <FormItem label="原图" prop="url">
          <Upload
            :before-upload="handleBeforeUpload"
            :on-success="handleUploadSuccess"
            :on-error="handleUploadError"
            :max-size="10240"
            action="/api/upload"
          >
            <Button icon="ios-cloud-upload-outline">选择图片</Button>
            <div class="upload-tip">支持 jpg、png、gif 格式，大小不超过 10MB</div>
          </Upload>
          <div v-if="formData.url" class="preview-image">
            <img :src="formData.url" alt="原图预览" />
          </div>
        </FormItem>

        <FormItem label="缩略图" prop="thumbnail">
          <Upload
            :before-upload="handleBeforeUpload"
            :on-success="handleThumbnailSuccess"
            :on-error="handleUploadError"
            :max-size="2048"
            action="/api/upload"
          >
            <Button icon="ios-cloud-upload-outline">选择缩略图</Button>
            <div class="upload-tip">支持 jpg、png、gif 格式，大小不超过 2MB</div>
          </Upload>
          <div v-if="formData.thumbnail" class="preview-image">
            <img :src="formData.thumbnail" alt="缩略图预览" />
          </div>
        </FormItem>

        <FormItem label="标签" prop="tags">
          <Select v-model="formData.tags" multiple filterable allow-create placeholder="请输入标签">
            <Option v-for="item in tagList" :key="item" :value="item">
              {{ item }}
            </Option>
          </Select>
        </FormItem>
      </Form>
    </Modal>

    <div class="img-group" v-if="fileList.length">
      <Tooltip
        :content="info.name"
        v-for="(info, i) in fileList"
        :key="`${i}-bai1-button`"
        placement="top"
      >
        <div class="tmpl-img-box">
          <Icon
            type="ios-trash"
            class="del-btn"
            color="red"
            @click="removeMaterialHandle(info.id)"
          />
          <Image
            lazy
            :src="info.imgUrl"
            fit="contain"
            height="100%"
            :alt="info.name"
            @click="addImgByElement"
          />
        </div>
      </Tooltip>
    </div>
    <div class="tip" v-else>暂无素材</div>
  </div>
</template>

<script setup name="ImportTmpl">
import { ref, reactive, onMounted } from 'vue';
import { Message } from 'view-ui-plus';
import { getMaterialTypes } from '@/api/material';
import { createdMaterial, getFileList, removeMaterial } from '@/api/user';
import { Utils } from '@kuaitu/core';

const APP_APIHOST = import.meta.env.APP_APIHOST;
const { selectFiles } = Utils;
const canvasEditor = inject('canvasEditor');

// 上传相关
const showUploadModal = ref(false);
const formRef = ref(null);
const typeList = ref([]);
const tagList = ref(['设计', '插画', '图标', '背景', '纹理', '装饰']);

// 表单数据
const formData = reactive({
  name: '',
  type_id: null,
  url: '',
  thumbnail: '',
  width: 0,
  height: 0,
  file_size: 0,
  file_type: '',
  tags: [],
});

// 表单验证规则
const rules = {
  name: [{ required: true, message: '请输入素材名称', trigger: 'blur' }],
  type_id: [{ required: true, message: '请选择素材类型', trigger: 'change' }],
  url: [{ required: true, message: '请上传原图', trigger: 'change' }],
  thumbnail: [{ required: true, message: '请上传缩略图', trigger: 'change' }],
};

// 获取素材类型列表
const fetchTypes = async () => {
  try {
    const res = await getMaterialTypes();
    typeList.value = res.data;
  } catch (error) {
    Message.error('获取素材类型失败');
  }
};

// 上传前检查
const handleBeforeUpload = (file) => {
  const isImage = file.type.startsWith('image/');
  if (!isImage) {
    Message.error('只能上传图片文件！');
    return false;
  }
  return true;
};

// 上传成功
const handleUploadSuccess = (response, file) => {
  formData.url = response.url;
  formData.width = file.width;
  formData.height = file.height;
  formData.file_size = file.size;
  formData.file_type = file.type;
  Message.success('原图上传成功');
};

// 缩略图上传成功
const handleThumbnailSuccess = (response) => {
  formData.thumbnail = response.url;
  Message.success('缩略图上传成功');
};

// 上传失败
const handleUploadError = () => {
  Message.error('上传失败，请重试');
};

// 提交表单
const handleUpload = () => {
  formRef.value.validate(async (valid) => {
    if (valid) {
      try {
        await createdMaterial({ data: formData });
        Message.success('素材上传成功');
        showUploadModal.value = false;
        // 重置表单
        formRef.value.resetFields();
        // 刷新列表
        getFileListHandle();
      } catch (error) {
        Message.error(error.response?.data?.error?.message || '上传失败');
      }
    }
  });
};

// 素材列表相关
const fileList = ref([]);
const getFileListHandle = () => {
  // 获取素材列表
  getFileList()
    .then((res) => {
      fileList.value = res.data.data.map((item) => {
        return {
          id: item.id,
          name: item.attributes.name,
          imgUrl: APP_APIHOST + item.attributes.img.data.attributes.url,
        };
      });
    })
    .catch((err) => {
      console.log(err);
    });
};

// 添加素材到画布
const addImgByElement = async (e) => {
  const imgItem = await canvasEditor.createImgByElement(e.target);
  canvasEditor.addBaseType(imgItem, {
    scale: true,
  });
};

// 删除素材
const removeMaterialHandle = (id) => {
  removeMaterial(id).finally(getFileListHandle);
};

onMounted(() => {
  fetchTypes();
  getFileListHandle();
});
</script>

<style scoped lang="less">
.my-material {
  height: 100%;
  display: flex;
  flex-direction: column;
}

.img-group {
  flex: 1;
  background: #eeeeeea1;
  border-radius: 10px;
  padding: 10px;
  margin-top: 10px;
  overflow-y: auto;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(134px, 1fr));
  gap: 10px;
}

.tmpl-img-box {
  width: 134px;
  height: 180px;
  padding: 5px;
  cursor: pointer;
  border-radius: 10px;
  text-align: center;
  position: relative;

  &:hover {
    background: #e3e3e3;
    .del-btn {
      opacity: 1;
      right: 5px;
    }
  }
}

.del-btn {
  z-index: 1;
  position: absolute;
  top: 5px;
  right: 5px;
  opacity: 0;
  transition: opacity 0.3s;
}

.tip {
  text-align: center;
  padding: 10px;
}

.upload-tip {
  font-size: 12px;
  color: #999;
  margin-top: 4px;
}

.preview-image {
  margin-top: 8px;
  img {
    max-width: 200px;
    max-height: 200px;
    border-radius: 4px;
  }
}
</style>
